
import rcontrolutil
import rcontrol
import Tkinter

class ROptionMenu(rcontrol.RControl):
	"""
	Optionmenu control.
	
	Drop-down menu control.
	
	
	Properties:
	*currentItem* - Set or get the currently chosen item, by value.
	Note-entries must be distinct
	"""
	
	_listDisplay=None
	_listValues=None
	_variable=None
	
	def __init__(self, listDisplays, listValues=None, defaultValue=None, fnCallback=None, parent=None):
		
		self._listDisplay = listDisplays
		if listValues==None: 
			self._listValues = list(self._listDisplay)
		else:
			if len(listDisplays)!=len(listValues): raise rcontrolutil.RException('length of listDisplays must equal length of listValues')
			self._listValues = listValues
		
		self._variable = Tkinter.StringVar()
		self._newWidgetManual(parent, Tkinter.OptionMenu,tklistargs=[self._variable]+self._listDisplay )
		
		if defaultValue == None:
			self._variable.set( self._listDisplay[0])
		else:
			self._variable.set( self._valueToDisplay(defaultValue))
		
		
		# Call the callback whenever the variable changes.
		if fnCallback!=None:
			traceCallback = lambda *args: fnCallback(self._displayToValue(self._variable.get()))
			self._variable.trace('w',traceCallback)
	
	
	def property_currentitem_get(self):
		return self._displayToValue(self._variable.get())
		
	def property_currentitem_set(self, value):
		self._variable.set(self._valueToDisplay(value))
	
	# a dictionary might be more efficient in some cases. For small lists I think it is about the same.
	def _valueToDisplay(self, value):
		if self._listValues==None:
			#values and displayed items are the same.
			return value
		try:
			index =self._listValues.index(value) # raises ValueError exception if not found
		except ValueError:
			raise rcontrolutil.PyRindPropertyException('The value does not exist.')
		return self._listDisplay[index]
		
	def _displayToValue(self, display):
		if self._listValues==None:
			#values and displayed items are the same.
			return display
		index =self._listDisplay.index(display) # raises ValueError exception if not found
		return self._listValues[index]
	
	
	_properties = {
		'currentItem':(property_currentitem_get, property_currentitem_set),
			'borderwidth': 'borderwidth',
			'borderstyle': ('relief',rcontrolutil.mapBorderstyle),
			
			'font': 'font',
		}
	


#~ self.jjj = w.add_optionmenu(['1','2','3'], listValues=['a','b','c'], defaultValue='c',fnCallback=self.trace)
